package com.example.onlinemusic.controller;

import com.example.onlinemusic.mapper.LoveMusicMapper;
import com.example.onlinemusic.mapper.MusicMapper;
import com.example.onlinemusic.model.Music;
import com.example.onlinemusic.model.User;
import com.example.onlinemusic.tools.Constant;
import com.example.onlinemusic.tools.ResponseBodyMessage;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: H_tao_X
 * Date: 2022-12-05
 * Time: 13:09
 */
@RestController // 组合注解 @Controller + @ResponseBody
@RequestMapping("/music")
public class MusicController {

    /**
     * 上传音乐
     * @return
     */
    @Autowired
    private LoveMusicMapper loveMusicMapper;

    @Autowired
    private MusicMapper musicMapper;
    // 从配置文件中 将 路径 读取出来
    @Value("${music.local.path}")
    private String SAVE_PATH;

    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> insertMusic(@RequestParam String singer,
                                                    @RequestParam("filename") MultipartFile file,
                                                    HttpServletRequest request,
                                                    HttpServletResponse resp) {
        // 1. 检查是否登录
            // 获取 session
        HttpSession session = request.getSession(false);
            // 判空
        if(session == null || session.getAttribute
                (Constant.USERINFO_SESSION_KEY) == null) {
            System.out.println("没有登录！");
            return new ResponseBodyMessage<>(-1,"请登录后上传!",false);
        }

        // 先查询数据库当中是否有当前音乐[歌曲名 + 歌手]
        // TODD:


        // 2. 上传到了服务器 ---- 拿到完整的文件名称 xxx.mp3
        String fileNameAndType = file.getOriginalFilename(); // 获取完整文件名称

        System.out.println("fileNameAndType" + fileNameAndType);

        String path = SAVE_PATH + fileNameAndType;

        File dest = new File(path); // dest 目录

        if(!dest.exists()) {
            dest.mkdir(); // 如果 dest（目录）不存在 创建目录
        }

        // 如果存在，通过 file.transferTo 将文件上传
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器上传失败！",false);
        }

        /**
         * 进行 数据库 上传
         */
        // 1. 先准备需要数据

            // 1.1 获取title xxx.mp3 -- > title = xxx
        int index = fileNameAndType.lastIndexOf(".");
        String title = fileNameAndType.substring(0,index); // 拿到 xxx

            // 1.2 获取 singer 已经确定，我们传参已经传了

            // 1.3 获取 userid
        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        int userid = user.getId();

            // 1.4 获取 url,播放音乐-》http请求
        String url = "/music/get?path="+title;

            //  1.5 获取 年-月-日
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            // 把当前的日期格式化为 time format（）格式化
        String time = sf.format(new Date());

        try {
            // 2. 调用 insert
            int ret = 0; // 插入影响的是行数，这里我们初始化一下，看看他等不等于1，等于1说明插入成功
            ret = musicMapper.insert(title,singer,time,url,userid);
            if(ret ==1 ) {
                // 上传成功 跳转到 音乐列表页
                resp.sendRedirect("/list.html");
                return new ResponseBodyMessage<>(0,"数据库上传成功",true);

            }else {
                return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
            }

        }catch (BindingException | IOException e) {
            dest.delete();
            return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
        }

        // 另外一个问题： 如果重复上传一首歌曲 能否上传成功? 可以
    }


    /**
     * 播放音乐模块设计
     */

    // 播放音乐的时候，路径：/music/get?path=xxx.mp3
    @RequestMapping("/get")
    public ResponseEntity<byte[]> get(String path) {
        File file = new File(SAVE_PATH + path);
        byte[] a = null;
        try {
            a = Files.readAllBytes(file.toPath());
            //Files.readAllBytes(String path) :
            // 读取文件中的所有字节，读入内存 ，参数path是文件的路径

            if(a == null) {
                // 无参ok方法返回OK状态
                // 有参ok方法返回body内容和OK状态
                return ResponseEntity.badRequest().build();
            }
            return ResponseEntity.ok(a);
        } catch (IOException e) {
            e.printStackTrace();
        }
            return ResponseEntity.badRequest().build();
//        return ResponseEntity.internalServerError().build();
//        return ResponseEntity.notFound().build();
    }


    /**
     * 删除音乐模块
     */

    /**
     * 删除单个音乐
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean> deleteMusicById(@RequestParam String id) {
        // 1. 先检查音乐是否存在
        int iid = Integer.parseInt(id);
        // 2. 如果存在进行删除
        Music music = musicMapper.findMusicById(iid);
        if(music == null) {
            return new ResponseBodyMessage<>(-1,"没有你要删除的音乐!",false);
        }else {
            // 2.1 删除数据库
            int ret = musicMapper.deleteMusicById(iid);
            // 如果 ret 等于1 说明 数据库数据删除成功
            if(ret == 1) {
                // 2.2 删除服务器上的数据(file)
                    // 这里需要拿到 title，可以通过 url 去拿，也可以直接 music.getTitle
                int index = music.getUrl().lastIndexOf("=");
                String fileName = music.getUrl().substring(index+1);
                File file = new File(SAVE_PATH + fileName + ".mp3");
                System.out.println("当前的路径: "  + file.getPath());

                if(file.delete()){

                    /**
                     * 删除音乐完善，同步删除lovemusic表当中的这个音乐
                     * 在 lovemusicMapper中新增 deleteMusicById（int musicId）
                     */
                    loveMusicMapper.deleteLoveMusicById(iid);

                    return  new ResponseBodyMessage<>(0,"服务器当中的音乐删除成功！",true);
                }else {
                    return  new ResponseBodyMessage<>(-1,"服务器当中的音乐删除失败！",false);
                }
            }else {
                return new ResponseBodyMessage<>(-1,"数据库当中的音乐没有删除成功",false);
            }

        }

    }

    /**
     * 批量删除
     * id[1,3,5,7,9]
     */
    @RequestMapping("/deleteSel")
    public ResponseBodyMessage<Boolean> deleteSelMusic(@RequestParam("id[]")
                                                               List<Integer> id) {
        System.out.println("所有的id:" + id);
        int sum = 0;
        // 因为是批量删除，这里用数组存储我们要删除的 音乐 id
        for (int i = 0; i < id.size(); i++) {
            // 1. 查询 音乐是否存在
            Music music = musicMapper.findMusicById(id.get(i));
            if (music == null) {
                System.out.println("没有这个id的音乐");
                return new ResponseBodyMessage<>(-1, "没有你要删除的音乐", false);
            }
            // 2. 如果音乐存在我们进行删除
            // 2.1 进行数据库删除
            int ret = musicMapper.deleteMusicById(id.get(i));
            if (ret == 1) {
                // 说明 数据库删除成功，进行服务器删除
                // 先拿到 title
                int index = music.getUrl().lastIndexOf("=");
                String fileName = music.getUrl().substring(index + 1);
                File file = new File(SAVE_PATH + fileName + ".mp3");
                System.out.println("当前路径:" + file.getPath());
                if (file.delete()) {
                    /**
                     * 完善音乐删除功能，同步删除 lovemusic表中的音乐
                     */
                    loveMusicMapper.deleteLoveMusicById(id.get(i));
                    sum += ret;
                } else {
                    return new ResponseBodyMessage<>(-1, "服务器当中的音乐删除失败！", false);
                }
            }else {
                return new ResponseBodyMessage<>(-1,"数据库当中音乐删除失败",false);
            }
        }
        // 判断 sum 的值是否等于 id.size 如果等于说明 删完啦
        if(sum == id.size()) {
            System.out.println("整体删除成功！");
            return new ResponseBodyMessage<>(0,"音乐删除成功",true);
        }else {
            System.out.println("整体删除失败！");
            return new ResponseBodyMessage<>(-1,"音乐删除失败",false);
        }
    }



    /**
     * 查询音乐模块
     * 实现：1、支持模糊查询 2、支持传入参数为空（传参 获取传参的 音乐信息，不传参 获取所有 音乐信息）
     */

    @RequestMapping("/findmusic")
    // 这里有一个小细节，我们可能不传参那么 我们的 @RequestParam 这里 需要 required = false
    public ResponseBodyMessage<List<Music>> findMusic(@RequestParam(required = false)
                                                                  String musicName) {
        List<Music> musicList = null;
        if(musicName != null) {
            // 不为空 查询指定音乐
            musicList = musicMapper.findMusicByName(musicName);
        }else {
            // 为空 查询所有音乐
            musicList = musicMapper.findMusic();
        }
        return new ResponseBodyMessage<>(0,"查询到了所有的音乐",musicList);
    }

}
